home *** CD-ROM | disk | FTP | other *** search
- /*
-
- CreateCopy XCMD v1.2
-
- ©1990-1 Apple Computer, Inc.; by Mike Byrne
-
- CreateCopy will create a copy of any file specified by the origin pathname (must be a full
- pathname) to the file specified by the destination. There must not be a file in the target
- directory with the same name as that specified in the destination path. Adhering to XCMD
- guidelines, this is not to take up more than 32K of memory, so this is *really* slow with
- large files (it does them 32K at a time).
-
- Form:
- CreateCopy <origin file pathname> <destination file pathname>
-
- # the MPW 3.2 build commands:
- C -b CreateCopy.c -mbg off
- Link -w -t STAK -c WILD -rt XCMD=604 ∂
- -m ENTRYPOINT ∂
- -sg CreateCopy ∂
- CreateCopy.c.o ∂
- "{Libraries}HyperXLib.o" ∂
- "{Libraries}Runtime.o" ∂
- "{Libraries}Interface.o" ∂
- "{CLibraries}StdCLib.o" ∂
- -o "teststack"
- */
-
- #include <Types.h>
- #include <Files.h>
- #include <string.h>
- #include <Memory.h>
- #include <Packages.h>
- #include "HyperXCmd.h"
-
- #define NULL 0L
- #define NIL 0L
-
- #define kNumParams 2
- #define k32kbytes 32768 //size of 32K
-
-
- /* prototypes */
- void ErrorBack(XCmdPtr paramPtr, char *message);
- void MoveLockParams ( XCmdPtr paramPtr, short paramCount );
- void UnlockParams ( XCmdPtr paramPtr, short paramCount );
-
-
-
- pascal void EntryPoint(XCmdPtr paramPtr)
- {
- short i,j;
- Handle theBuffer;
- char orgName[301];
- char orgVol[34];
- char destName[301];
- char destVol[34];
- short orgVRefNum = 0;
- short destVRefNum = 0;
- short orgRef;
- short destRef;
- FInfo fndrInfo;
- OSType type = 0;
- OSType creator = 0;
- long fileLength;
- long fullBlocks;
- long partialBlock;
- long blockSize = k32kbytes;
-
-
-
- /* move high and lock the parameters. */
- MoveLockParams(paramPtr, paramPtr->paramCount);
-
- /* check for syntax or copyright help request */
- if (!strcmp( (char*)*paramPtr->params[0], "!") ) {
- ErrorBack(paramPtr, "v1.2, by Mike Byrne, ©1990-1 Apple Computer, Inc.");
- UnlockParams(paramPtr, paramPtr->paramCount);
- return;
- } else if (!strcmp ( (char*)*paramPtr->params[0], "?") ) {
- ErrorBack(paramPtr, "CreateCopy syntax is 'CreateCopy <origin filepath> <destination filepath>'");
- UnlockParams(paramPtr, paramPtr->paramCount);
- return;
- }
-
- /* check for correct number of parameters *.
- if (paramPtr->paramCount != kNumParams) {
- ErrorBack(paramPtr, "Error: CreateCopy syntax is 'CreateCopy <origin filepath> <destination filepath>'");
- return;
- }
-
-
- /* THE ORIGIN FILE
- extract the volume name from the handle, copy to a pas string,
- and get the volume reference number of the volume */
- for (i=0; ((*(paramPtr->params[0]))[i] != ':' && (i < 33)); i++)
- { orgVol[i] = (*(paramPtr->params[0]))[i]; }
- orgVol[i] = ':';
- orgVol[i+1] = '\0';
- c2pstr(orgVol);
-
- if (SetVol(orgVol, orgVRefNum) != noErr) { // toolbox
- ErrorBack(paramPtr, "Error: Could not set the default origin volume");
- UnlockParams(paramPtr, kNumParams);
- return;
- }
-
- if (GetVol(&orgVol, &orgVRefNum) != noErr) { // toolbox
- ErrorBack(paramPtr, "Error: Could not find the origin volume requested.");
- UnlockParams(paramPtr, kNumParams);
- return;
- }
-
- /* now, copy the rest of the pathname to the partial pathname and convert it. */
- for (j=i; (j <= strlen((*(paramPtr->params[0]))) && (j < 300)); j++)
- { orgName[j-i] = (*(paramPtr->params[0]))[j]; }
- c2pstr(orgName);
-
- /* open the origin file */
- if ( FSOpen(orgName, orgVRefNum, &orgRef) != noErr) { // toolbox
- ErrorBack(paramPtr, "Error: Cannot open source file.");
- UnlockParams(paramPtr, kNumParams);
- return;
- }
-
- /* get the type and creator of the origin file */
- if (GetFInfo(orgName, orgVRefNum, &fndrInfo) != noErr) { // toolbox
- ErrorBack(paramPtr, "Error: Could not access file type and creator.");
- UnlockParams(paramPtr, kNumParams);
- FSClose(orgRef);
- return;
- }
- type = fndrInfo.fdType;
- creator = fndrInfo.fdCreator;
-
- /* find out how big the origin file is */
- if ( GetEOF(orgRef, &fileLength) != noErr) { // toolbox
- ErrorBack(paramPtr, "Error: Cannot find end-of-file for the origin file.");
- UnlockParams(paramPtr, kNumParams);
- FSClose(orgRef);
- return;
- }
-
-
- /* reset loop counters */
- i = j = 0;
- /* THE DESTINATION FILE
- extract the volume name from the handle, copy to a pas string,
- and get the volume reference number of the volume */
- for (i=0; ((*(paramPtr->params[1]))[i] != ':' && (i < 33)); i++)
- { destVol[i] = (*(paramPtr->params[1]))[i]; }
- destVol[i] = ':';
- destVol[i+1] = '\0';
- c2pstr(destVol);
-
- if (SetVol(destVol, destVRefNum) != noErr) { // toolbox
- ErrorBack(paramPtr, "Error: Could not set the default destination volume");
- UnlockParams(paramPtr, kNumParams);
- FSClose(orgRef);
- return;
- }
-
- if (GetVol(&destName, &destVRefNum) != noErr) { // toolbox
- ErrorBack(paramPtr, "Error: Could not find the destination volume requested.");
- UnlockParams(paramPtr, kNumParams);
- FSClose(orgRef);
- return;
- }
-
- /* now, copy the rest of the pathname to the partial pathname and convert it. */
- for (j=i; (j <= strlen((*(paramPtr->params[1]))) && (j < 300)); j++)
- { destName[j-i] = (*(paramPtr->params[1]))[j]; }
- c2pstr(destName);
-
- /* now, create the destination file. */
- if (Create(destName, destVRefNum, creator, type) != noErr) { // toolbox
- ErrorBack(paramPtr, "Error: Could not create destination file");
- UnlockParams(paramPtr, kNumParams);
- FSClose(orgRef);
- return;
- }
-
- /* open the destination file */
- if (FSOpen(destName, destVRefNum, &destRef) != noErr) { // toolbox
- ErrorBack(paramPtr, "Error: Could not open destination file.");
- UnlockParams(paramPtr, kNumParams);
- FSClose(orgRef);
- return;
- }
-
- /* THE ACTUAL COPYING PART */
- /* check out how many blocks will be necessary. */
- fullBlocks = fileLength / blockSize;
- partialBlock = fileLength % blockSize;
-
-
- if ((theBuffer = NewHandleClear((Size)blockSize)) == 0) {
- ErrorBack(paramPtr, "Error: Cannot allocate the 32K for the copy.");
- UnlockParams(paramPtr, kNumParams);
- FSClose(orgRef);
- FSClose(destRef);
- return;
- }
-
- MoveHHi(theBuffer);
-
- /* iterate through the number of 32K blocks */
- for (i=1; i <= fullBlocks; i++) {
- /* read for 32K (or whatever) */
- if (FSRead(orgRef, &blockSize, *theBuffer) != noErr) { // toolbox
- ErrorBack(paramPtr, "Error: Could not read from origin file");
- DisposHandle(theBuffer);
- UnlockParams(paramPtr, kNumParams);
- FSClose(orgRef);
- FSClose(destRef);
- return;
- }
- /* write however many were read in */
- if (FSWrite(destRef, &blockSize, *theBuffer) != noErr) { // toolbox
- ErrorBack(paramPtr, "Error: Could not write to destination file.");
- DisposHandle(theBuffer);
- UnlockParams(paramPtr, kNumParams);
- FSClose(orgRef);
- FSClose(destRef);
- return;
- }
- }
-
- /* now, do the partial block */
- if (FSRead(orgRef, &partialBlock, *theBuffer) != noErr) { // toolbox
- ErrorBack(paramPtr, "Error: Could not read from origin file");
- DisposHandle(theBuffer);
- UnlockParams(paramPtr, kNumParams);
- FSClose(orgRef);
- FSClose(destRef);
- return;
- }
- /* write however many were read in */
- if (FSWrite(destRef, &partialBlock, *theBuffer) != noErr) { // toolbox
- ErrorBack(paramPtr, "Error: Could not write to destination file.");
- DisposHandle(theBuffer);
- UnlockParams(paramPtr, kNumParams);
- FSClose(orgRef);
- FSClose(destRef);
- return;
- }
-
- /* okay, the copying of the data fork is finished. close the data forks. */
- FSClose(orgRef);
- FSClose(destRef);
-
- /* all that crap we did? do it again for the resource fork... */
- /* open the origin file */
- if ( OpenRF(orgName, orgVRefNum, &orgRef) != noErr) { // toolbox
- ErrorBack(paramPtr, "Error: Cannot open source file resource fork.");
- DisposHandle(theBuffer);
- UnlockParams(paramPtr, kNumParams);
- return;
- }
-
- /* find out how big the origin file is */
- if ( GetEOF(orgRef, &fileLength) != noErr) { // toolbox
- ErrorBack(paramPtr, "Error: Cannot find end-of-file for the origin file resource fork.");
- DisposHandle(theBuffer);
- UnlockParams(paramPtr, kNumParams);
- FSClose(orgRef);
- return;
- }
-
- /* open the destination file */
- if (OpenRF(destName, destVRefNum, &destRef) != noErr) { // toolbox
- ErrorBack(paramPtr, "Error: Could not open destination file resource fork.");
- DisposHandle(theBuffer);
- UnlockParams(paramPtr, kNumParams);
- FSClose(orgRef);
- return;
- }
-
- /* set up block sizes */
- fullBlocks = fileLength / blockSize;
- partialBlock = fileLength % blockSize;
-
- /* iterate through the number of 32K blocks */
- for (i=1; i <= fullBlocks; i++) {
- /* read for 32K (or whatever) */
- if (FSRead(orgRef, &blockSize, *theBuffer) != noErr) { // toolbox
- ErrorBack(paramPtr, "Error: Could not read from origin file");
- DisposHandle(theBuffer);
- UnlockParams(paramPtr, kNumParams);
- FSClose(orgRef);
- FSClose(destRef);
- return;
- }
- /* write however many were read in */
- if (FSWrite(destRef, &blockSize, *theBuffer) != noErr) { // toolbox
- ErrorBack(paramPtr, "Error: Could not write to destination file.");
- DisposHandle(theBuffer);
- UnlockParams(paramPtr, kNumParams);
- FSClose(orgRef);
- FSClose(destRef);
- return;
- }
- }
-
- /* now, do the partial block */
- if (FSRead(orgRef, &partialBlock, *theBuffer) != noErr) { // toolbox
- ErrorBack(paramPtr, "Error: Could not read from origin file");
- DisposHandle(theBuffer);
- UnlockParams(paramPtr, kNumParams);
- FSClose(orgRef);
- FSClose(destRef);
- return;
- }
- /* write however many were read in */
- if (FSWrite(destRef, &partialBlock, *theBuffer) != noErr) { // toolbox
- ErrorBack(paramPtr, "Error: Could not write to destination file.");
- DisposHandle(theBuffer);
- UnlockParams(paramPtr, kNumParams);
- FSClose(orgRef);
- FSClose(destRef);
- return;
- }
-
- /* okay, the copying of the resource fork is finished. close 'em, clean up, go home. */
- FSClose(orgRef);
- FSClose(destRef);
- DisposHandle(theBuffer);
- UnlockParams(paramPtr, kNumParams);
- return;
- }
-
-
-
-
-
-
- /* allocate and load up paramPtr->returnValue with a string
- -------------------------------------------------------- */
- void ErrorBack(XCmdPtr paramPtr, char *message)
- {
- Handle mesHnd;
-
- /*
- Allocate space for an error message.
- Copy the string into it.
- Return the handle to HyperCard.
- */
- mesHnd = NewHandle((long)(strlen(message)+1));
- if (mesHnd == nil) return;
- strcpy((char *)*mesHnd,message);
- paramPtr->returnValue = mesHnd;
- }
-
-
-
- /* move high and lock down all parameters (watch that these are read-only)
- ----------------------------------------------------------------------- */
- void MoveLockParams ( XCmdPtr paramPtr, short paramCount )
- {
- short i;
-
- for(i=0; i <= paramCount-1; i++)
- {
- MoveHHi(paramPtr->params[i]);
- HLock(paramPtr->params[i]);
- }
- }
-
-
-
-
- /* unlock all parameter handles in the XCmdBlock
- --------------------------------------------- */
- void UnlockParams ( XCmdPtr paramPtr, short paramCount )
- { short i;
-
- for(i=0; i <= paramCount-1; i++)
- { HUnlock(paramPtr->params[i]);}
- }
-